﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Data.OleDb;
using System.Data.SqlClient;
using ICSharpCode.SharpZipLib.Zip;

namespace MyBook66_To_FB2
{

    public partial class Form1 : Form
    {
        public static OleDbConnection DBCon;
        public static DataSet ds;
        public static MyBook66BookLister BookLister;
        public static MyBook66ChapterLister CPL;
        //public static string MyBook66DBConnectString = "";

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {


        }

        private void button1_Click(object sender, EventArgs e)
        {
            osd.ShowDialog();
            DBCon = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + osd.FileName);
            BookLister = new MyBook66BookLister(osd.FileName, ref DBCon);
            BookLister.FillBookName(ref booklist);
            //MyBook66DBConnectString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + osd.FileName;
            BookLister.FillBookGroup(ref grplst);
            grplst.SelectedIndex = 0;
            //button3.Enabled = true;
            button1.Enabled = false;
            button2.Enabled = true;
            booklist.Enabled = true;
            grplst.Enabled = true;
            button1.Visible = false;
            button4.Enabled = true;

        }

        private void booklist_SelectedIndexChanged(object sender, EventArgs e)
        {
            button1.Text = BookLister.GetBookIDFromName(booklist.Text);
            CPL = new MyBook66ChapterLister(BookLister.GetBookIDFromName(booklist.Text), ref DBCon);
            CPL.Path = Path.GetDirectoryName(osd.FileName);
            CPL.FillChapterList(ref listBox1);
            label1.Text = CPL.FilePath(0);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            MyBook66ToFB2Converter conv = new MyBook66ToFB2Converter();
                       //conv.CreateFB2(CPL.Path + "\\" + booklist.Text + ".fb2", booklist.Text, ref CPL);
            conv.isKeepCache = cb_keepcache.Checked;
            conv.isUseCache = cb_usecache.Checked;
            conv.isToFBZ = cb_useFBZ.Checked;
            //conv.CreateFB2(CPL.Path + "\\" + booklist.Text + ".fb2", booklist.Text, osd.FileName);
            conv.CreateFB2(Path.GetDirectoryName(osd.FileName)+"\\"+booklist.Text +".fb2",booklist.Text,osd.FileName );


            button1.Text = "Done";
        }

        private void bt_buildall_Click(object sender, EventArgs e)
        {


        }

        private void button3_Click(object sender, EventArgs e)
        {
            MyBook66ToFB2Converter conv;
            for (int i = 0; i < booklist.Items.Count; i++)
            {
                conv = new MyBook66ToFB2Converter();
                conv.isUseCache = cb_usecache.Checked;
                conv.isKeepCache = cb_keepcache.Checked;
                conv.CreateFB2(Path.GetDirectoryName(osd.FileName) + "\\" + booklist.Items[i].ToString() + ".fb2", booklist.Items[i].ToString(), osd.FileName);
            }

        }
        private void btn_BuildNew_Click(object sender, EventArgs e)
        {
            //generate list containing all new chapters of the books



        }

        public class MyBook66BookLister
        {
            private OleDbDataAdapter DBAdp, DBGAdp,DBNewCp;
            private DataSet Ds_BookList, Ds_GroupList,ds_NewCPs;
            public MyBook66BookLister(string FileName, ref OleDbConnection DBCon)
            {
                if (File.Exists(FileName))
                {
                    DBCon.Open();
                    Ds_BookList = new DataSet();
                    Ds_GroupList = new DataSet();
                    ds_NewCPs = new DataSet();

                    try //get book info
                    {
                        DBAdp = new OleDbDataAdapter(@"select NovelID,NovelName,LB from book_novel", DBCon);
                        DBAdp.Fill(Ds_BookList);
                    }
                    catch (Exception ex_db)
                    {
                        throw ex_db;
                    }

                    try //get group info
                    {
                        DBGAdp = new OleDbDataAdapter(@"select DM,MC from dic_noveltype", DBCon);
                        DBGAdp.Fill(Ds_GroupList);

                    }
                    catch (Exception ex_db)
                    {
                        throw ex_db;
                    }
                    try//get new chapter book ids
                    {
                        DBNewCp = new OleDbDataAdapter(@"select NovelID from book_NovelContent where bIsRead='0'", DBCon);
                        DBNewCp.Fill(ds_NewCPs);


                    }
                    catch (Exception ex)
                    {
                        throw ex;

                    }


                    DBCon.Close();
                }
                else
                {
                    Exception ex = new Exception("Error Finding the DB FileName");
                    throw ex;
                }

            }
            public void FillBookName(ref ComboBox listbox)
            {
                listbox.Items.Clear();

                for (int i = 0; i < Ds_BookList.Tables[0].Rows.Count; i++)
                {
                    listbox.Items.Add(Ds_BookList.Tables[0].Rows[i].ItemArray[1].ToString());
                }
            }
            public void FillBookName(ref CheckedListBox listbox, string group_by)
        {
            listbox.Items.Clear();
            listbox.Enabled = false;
            if (group_by.Contains("@"))
            {
                if (group_by == "@All")
                {
                    for (int i = 0; i < Ds_BookList.Tables[0].Rows.Count; i++)
                    {
                        listbox.Items.Add(Ds_BookList.Tables[0].Rows[i].ItemArray[1].ToString(), true);

                    }
                    listbox.Enabled = true;
                    return;
                }
                if (group_by == "@HasNewChapters")
                {
                    for (int i = 0; i < ds_NewCPs.Tables[0].Rows.Count; i++)
                    {
                        
                        if (!(listbox.Items.Contains(GetBookNameFromID(ds_NewCPs.Tables[0].Rows[i].ItemArray[0].ToString()))))
                        {
                            listbox.Items.Add(GetBookNameFromID(ds_NewCPs.Tables[0].Rows[i].ItemArray[0].ToString()), true);
                        }
                    }
                    listbox.Enabled = true;

                }
            }



            else
            {
                int group_id = -1 ;
                for (int i = 0; i < Ds_GroupList.Tables[0].Rows.Count; i++)
                {
                    if (Ds_GroupList.Tables[0].Rows[i].ItemArray[1].ToString() == group_by)
                    {
                        group_id = i;
                    }
                }
                if (group_id == -1)
                {
                    listbox.Items.Add("This Group Dos Not Exists!!");
                    return;
                }
                string LBN = "";
                LBN = Ds_GroupList.Tables[0].Rows[group_id].ItemArray[0].ToString();
                //find if there is books tagged in this group
                for (int i = 0; i < Ds_BookList.Tables[0].Rows.Count; i++)
                {
                    if (Ds_BookList.Tables[0].Rows[i].ItemArray[2].ToString() == LBN)
                    {
                        listbox.Items.Add(Ds_BookList.Tables[0].Rows[i].ItemArray[1].ToString(),true);
                    }
                }
                if (listbox.Items.Count == 0)
                {
                    listbox.Items.Add("There is noBook in this Group!!!");
                }
                else listbox.Enabled = true;
            }
        }
            public void FillBookGroup(ref ComboBox listbox)
            {
                
                listbox.Items.Clear();
                listbox.Items.Add("@All");
                listbox.Items.Add("@HasNewChapters");
                for (int i = 0; i < Ds_GroupList.Tables[0].Rows.Count; i++)
                {
                    listbox.Items.Add(Ds_GroupList.Tables[0].Rows[i].ItemArray[1].ToString());
                }


            }
            public string GetBookIDFromName(string BookName)
            {
                string id = "_BOOK_NOT_FOUND_";
                for (int i = 0; i < Ds_BookList.Tables[0].Rows.Count; i++)
                {
                    if (BookName == Ds_BookList.Tables[0].Rows[i].ItemArray[1].ToString())
                        id = Ds_BookList.Tables[0].Rows[i].ItemArray[0].ToString();
                }
                return id;
            }
            public string GetBookNameFromID(string BookID)
            {
                string id = "_BOOK_NOT_FOUND_";
                for (int i = 0; i < Ds_BookList.Tables[0].Rows.Count; i++)
                {
                    if (BookID == Ds_BookList.Tables[0].Rows[i].ItemArray[0].ToString())
                        id = Ds_BookList.Tables[0].Rows[i].ItemArray[1].ToString();
                }
                return id;
            }
        }
        public class MyBook66ChapterLister
        {
            private OleDbDataAdapter DBAdp;
            private DataSet DS_Chapters;
            private string sPath = "";
            public string Path
            {
                set
                {
                    sPath = value;
                }
                get
                {
                    return sPath; ;
                }


            }
            private int iCount = 0;
            public int Count
            {
                get
                {
                    return iCount;
                }
            }
            private string sBookID = "";
            public string BookID
            {
                get
                {
                    return sBookID;
                }

            }
            public string FilePath(int idx)
            {
                string pth = "";
                pth = sPath + "\\chm\\" + BookID + "\\" + DS_Chapters.Tables[0].Rows[idx].ItemArray[0].ToString() + ".htm";
                return pth;
            }
            public MyBook66ChapterLister(string BookID, ref OleDbConnection DBCon)
            {
                DBCon.Open();
                DS_Chapters = new DataSet();
                sBookID = BookID;
                try //get chapters from BookID
                {
                    DBAdp = new OleDbDataAdapter("select id,Title,Volume from book_NovelContent where NovelID='" + BookID + "' order by id asc", DBCon);
                    DBAdp.Fill(DS_Chapters);
                }

                catch (Exception ex_db) { throw ex_db; }
                iCount = DS_Chapters.Tables[0].Rows.Count;
                DBCon.Close();
            }
            public void FillChapterList(ref ListBox listbox)
            {
                listbox.Items.Clear();
                for (int i = 0; i < DS_Chapters.Tables[0].Rows.Count; i++)
                {
                    listbox.Items.Add(DS_Chapters.Tables[0].Rows[i].ItemArray[1].ToString());
                }
            }
            public string ChapterTitle(int idx)
            {
                String tmps = "";
                tmps = DS_Chapters.Tables[0].Rows[idx].ItemArray[1].ToString();
                return tmps;
            }


        }
        public class MyBook66ToFB2Converter
        {
            public bool isUseCache = true;
            public bool isKeepCache = true;
            public bool isToFBZ = false;
            public void Prepare(string HTMLFileName, string ChapterTitle)
            {

                if (File.Exists(HTMLFileName))
                {
                    string FileInput = File.ReadAllText(HTMLFileName, Encoding.Default);
                    int start = FileInput.IndexOf("<!--BookContent Start-->") + 24;
                    int endp = FileInput.IndexOf("<!--BookContent End-->");
                    FileInput = FileInput.Substring(start, endp - start);
                    FileInput = FileInput.Replace("&nbsp;", " ");
                    FileInput = FileInput.Replace("<br>", "</p><p>");
                    FileInput = FileInput.Replace("</br>", "</p><p>");
                    FileInput = "<section><title><p>" + ChapterTitle + "</p></title><p>" + FileInput + "</p></section>";
                    File.WriteAllText(HTMLFileName + ".fb2section", FileInput, Encoding.UTF8);
                }
                else
                {
                    string FileInput = "This Chapter was not found on storage, check your mybook66 for that....";
                    FileInput = "<section><title><p>" + ChapterTitle + "</p></title><p>" + FileInput + "</p></section>";
                    File.WriteAllText(HTMLFileName + ".fb2section", FileInput, Encoding.UTF8);


                }

            }
            public void CreateFB2(string FileName, string BookTitle, ref MyBook66ChapterLister chapters)
            {

                for (int i = 0; i < chapters.Count; i++)
                {
                    if (File.Exists(chapters.FilePath(i) + ".fb2section"))
                    { //using pre created fb2 caches
                        if (isUseCache == false)
                        {
                            Prepare(chapters.FilePath(i), chapters.ChapterTitle(i));
                        }
                    }
                    else
                    {
                        Prepare(chapters.FilePath(i), chapters.ChapterTitle(i));
                    }
                }


                using (StreamWriter sw = File.CreateText(FileName))
                {
                    try
                    {
                        sw.WriteLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
                        sw.WriteLine("<FictionBook xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns=\"http://www.gribuser.ru/xml/fictionbook/2.0\">");
                        sw.WriteLine("<description><title-info><genre match = \"0\">ChineseNetNovels</genre>");
                        sw.WriteLine("<author><first-name>MyBook66 Downloaded</first-name><last-name>Almost All Piracy....</last-name></author>");
                        sw.WriteLine("<book-title>" + BookTitle + "</book-title>");
                        sw.WriteLine("<date value =\"" + DateTime.Today.ToString() + "\">" + DateTime.Today.Year.ToString() + "</date>");
                        sw.WriteLine("<lang>ZH_CN</lang></title-info>");
                        sw.WriteLine("<document-info><author><nickname>Anonymous</nickname></author>");
                        sw.WriteLine("<program-used>MyBook66_To_FB2</program-used></document-info></description>");
                        sw.WriteLine("<body><title><p>" + BookTitle + "</p></title>");
                        sw.Close();
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }



                    for (int i = 0; i < chapters.Count; i++)
                    {
                        File.AppendAllText(FileName, File.ReadAllText(chapters.FilePath(i) + ".fb2section"));
                    }
                    File.AppendAllText(FileName, "</body></FictionBook>");


                }





            }
            public void CreateFB2(string FileName, string BookTitle, string DBFileName)
            {   

                //step 1 : connect to DB
                string DBConnectstring =  @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + DBFileName;
                OleDbConnection dbc = new OleDbConnection(DBConnectstring);
                dbc.Open();
                //step 2 : get book id from title
                DataSet ds_bookid = new DataSet();
                OleDbDataAdapter dba = new OleDbDataAdapter(@"select NovelID,NovelName from book_novel where NovelName='"+BookTitle+"'",dbc);
                dba.Fill(ds_bookid);
                if (ds_bookid.Tables[0].Rows[0].ItemArray[1].ToString() == BookTitle)
                {//check if db has the Book named BookTitle
                    string Book_ID = ds_bookid.Tables[0].Rows[0].ItemArray[0].ToString();
                    DataSet ds_Chapters = new DataSet();
                    OleDbDataAdapter dac = new OleDbDataAdapter(@"select id,Title,Volume from book_NovelContent where NovelID='" + Book_ID + "' order by id asc", dbc);
                    dac.Fill(ds_Chapters);
                    
                    int Chapter_Count = ds_Chapters.Tables[0].Rows.Count;
                    string ResourceHtmlFileName,ResourceTitle = "";

                    StreamWriter sw = File.CreateText(FileName);
                    //title filled
                    sw.WriteLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
                    sw.WriteLine("<FictionBook xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns=\"http://www.gribuser.ru/xml/fictionbook/2.0\">");
                    sw.WriteLine("<description><title-info><genre match = \"0\">ChineseNetNovels</genre>");
                    sw.WriteLine("<author><first-name>MyBook66 Downloaded</first-name><last-name>Almost All Piracy....</last-name></author>");
                    sw.WriteLine("<book-title>" + BookTitle + "</book-title>");
                    sw.WriteLine("<date value =\"" + DateTime.Today.ToString() + "\">" + DateTime.Today.Year.ToString() + "</date>");
                    sw.WriteLine("<lang>ZH_CN</lang></title-info>");
                    sw.WriteLine("<document-info><author><nickname>Anonymous</nickname></author>");
                    sw.WriteLine("<program-used>MyBook66_To_FB2</program-used></document-info></description>");
                    sw.WriteLine("<body><title><p>" + BookTitle + "</p></title>");
                    sw.Close();



                    if (isUseCache)
                    {
                        //check for cachefiles ,if not found ,create one ...
                        for (int i = 0; i < Chapter_Count; i++)
                        {
                            ResourceHtmlFileName = Path.GetDirectoryName(DBFileName) + "\\chm\\" + Book_ID + "\\" + ds_Chapters.Tables[0].Rows[i].ItemArray[0].ToString() + ".htm";
                            ResourceTitle = ds_Chapters.Tables[0].Rows[i].ItemArray[2].ToString() +"  " + ds_Chapters.Tables[0].Rows[i].ItemArray[1].ToString();
                            if (File.Exists(ResourceHtmlFileName + ".fb2section"))
                            {
                                //cache would be used.....
                                File.AppendAllText(FileName, File.ReadAllText(ResourceHtmlFileName + ".fb2section"));

                            }
                            else
                            {   //create cache file.....then add to creation fb2 file
                                Prepare(ResourceHtmlFileName,ResourceTitle);
                                File.AppendAllText(FileName, File.ReadAllText(ResourceHtmlFileName + ".fb2section"));
                            }
                        }

                        //finalize the fb2 book
                        File.AppendAllText(FileName, "</body></FictionBook>");
                        if (isToFBZ)
                        {
                            ICSharpCode.SharpZipLib.Zip.FastZip fbzout = new FastZip();
                            fbzout.CreateZip(Path.ChangeExtension(FileName, ".fbz"), Path.GetDirectoryName(DBFileName), false, Path.GetFileName(FileName));
                            File.Delete(FileName);
                        }
                        //join cache files

                        if (isKeepCache)
                        {
                        }
                        else
                        {
                            //delete every cache file created
                            for (int i = 0; i < Chapter_Count; i++)
                            {
                                ResourceHtmlFileName = Path.GetDirectoryName(DBFileName) + "\\chm\\" + Book_ID + "\\" + ds_Chapters.Tables[0].Rows[i].ItemArray[0].ToString() + ".htm.fb2section";
                                if (File.Exists(ResourceHtmlFileName)) File.Delete(ResourceHtmlFileName);
                            }
                        }

                    }
                    if (isUseCache  == false )
                    {//do not use cache ,do not keep cache

                        for (int i = 0; i < Chapter_Count; i++)
                        {

                            ResourceHtmlFileName = Path.GetDirectoryName(DBFileName) + "\\chm\\" + Book_ID + "\\" + ds_Chapters.Tables[0].Rows[i].ItemArray[0].ToString() + ".htm";
                            ResourceTitle = ds_Chapters.Tables[0].Rows[i].ItemArray[2].ToString() + "  "+ ds_Chapters.Tables[0].Rows[i].ItemArray[1].ToString();


                            if (File.Exists(ResourceHtmlFileName))
                            {
                                string FileInput = File.ReadAllText(ResourceHtmlFileName, Encoding.Default);
                                int start = FileInput.IndexOf("<!--BookContent Start-->") + 24;
                                int endp = FileInput.IndexOf("<!--BookContent End-->");
                                FileInput = FileInput.Substring(start, endp - start);
                                FileInput = FileInput.Replace("&nbsp;", " ");
                                FileInput = FileInput.Replace("<br>", "</p><p>");
                                FileInput = FileInput.Replace("</br>", "</p><p>");
                                FileInput = "<section><title><p>" + ResourceTitle + "</p></title><p>" + FileInput + "</p></section>";
                                File.AppendAllText(FileName, FileInput, Encoding.UTF8);
                            }
                            else
                            {
                                string FileInput = "This Chapter was not found on storage, check your mybook66 for that....";
                                FileInput = "<section><title><p>" + ResourceTitle + "</p></title><p>" + FileInput + "</p></section>";
                                File.AppendAllText(FileName, FileInput, Encoding.UTF8);
                            }


                        }

                        //finalize the fb2 book
                        File.AppendAllText(FileName, "</body></FictionBook>");
                        if (isToFBZ)
                        {
                            ICSharpCode.SharpZipLib.Zip.FastZip fbzout = new FastZip();
                            fbzout.CreateZip(Path.ChangeExtension(FileName, ".fbz"), Path.GetDirectoryName(DBFileName), false, Path.GetFileName(FileName));
                            File.Delete(FileName);
                        }
                    }
                }
                else
                {
                }



                //last step : cleanning up
                dbc.Close();
                dbc.Dispose();
                ds_bookid.Dispose();
                dba.Dispose();




            }
        }

        private void label2_Click(object sender, EventArgs e)
        {

        }

        private void grplst_SelectedIndexChanged(object sender, EventArgs e)
        {
            BookLister.FillBookName(ref bklst, grplst.Text);

        }

        private void button4_Click(object sender, EventArgs e)
        {
            pb1.Minimum = 0;
            pb1.Maximum = bklst.CheckedItems.Count;
            pb1.Step = 1;
            pb1.Value = 0;

            MyBook66ToFB2Converter conv = new MyBook66ToFB2Converter();
            conv.isKeepCache = cb_keepcache.Checked;
            conv.isUseCache = cb_usecache.Checked;
            conv.isToFBZ = cb_useFBZ.Checked;
            string pth = Path.GetDirectoryName(osd.FileName);

            for (int i = 0; i < bklst.CheckedItems.Count; i++)
            {
                //conv.CreateFB2(CPL.Path + "\\" + booklist.Text + ".fb2", booklist.Text, osd.FileName);

                conv.CreateFB2(pth + "\\" + bklst.CheckedItems[i].ToString() + ".fb2", bklst.CheckedItems[i].ToString(), osd.FileName);
                pb1.Value = pb1.Value + 1;
            }
            
        }

        private void button3_Click_1(object sender, EventArgs e)
        {
        }

        private void cb_usecache_CheckedChanged(object sender, EventArgs e)
        {

        }



    }
}
